/**
  ******************************************************************************
  * @file    usbd_cdc_core.c
  * @author  MCD Application Team
  * @version V1.0.0
  * @date    22-July-2011
  * @brief   This file provides the high layer firmware functions to manage the 
  *          following functionalities of the USB CDC Class:
  *           - Initialization and Configuration of high and low layer
  *           - Enumeration as CDC Device (and enumeration for each implemented memory interface)
  *           - OUT/IN data transfer
  *           - Command IN transfer (class requests management)
  *           - Error management
  *           
  *  @verbatim
  *      
  *          ===================================================================      
  *                                CDC Cflass Driver Description
  *          =================================================================== 
  *           This driver manages the "Universal Serial Bus Class Definitions for Communications Devices
  *           Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus 
  *           Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007"
  *           This driver implements the following aspects of the specification:
  *             - Device descriptor management
  *             - Configuration descriptor management
  *             - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN)
  *             - Requests management (as described in section 6.2 in specification)
  *             - Abstract Control Model compliant
  *             - Union Functional collection (using 1 IN endpoint for control)
  *             - Data interface class

  *           @note
  *             For the Abstract Control Model, this core allows only transmitting the requests to
  *             lower layer dispatcher (ie. usbd_cdc_vcp.c/.h) which should manage each request and
  *             perform relative actions.
  * 
  *           These aspects may be enriched or modified for a specific user application.
  *          
  *            This driver doesn't implement the following aspects of the specification 
  *            (but it is possible to manage these features with some modifications on this driver):
  *             - Any class-specific aspect relative to communication classes should be managed by user application.
  *             - All communication classes other than PSTN are not managed
  *      
  *  @endverbatim
  *                                  
  ******************************************************************************               
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
  ******************************************************************************
  */ 

/* Includes ------------------------------------------------------------------*/
#include "usbd_cdc_core.h"
#include "usbd_desc.h"
#include "usbd_req.h"
#include "main.h"
#include "../../../../../DDIC/AllDDIC.h"

u16 crc16_data1 = 0;
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
  * @{
  */


/** @defgroup usbd_cdc 
  * @brief usbd core module
  * @{
  */ 

/** @defgroup usbd_cdc_Private_TypesDefinitions
  * @{
  */ 
/**
  * @}
  */ 


/** @defgroup usbd_cdc_Private_Defines
  * @{
  */ 
/**
  * @}
  */ 
u8 NUM=0;
u8 Valid_BMP_No = 0;
OLED_Para OLED;
u32 WriteAddress = Inter_Flash_Addr;
u32 buffer1[BMP_R_Byte_Max-1];
u8	Uart_rx_flag = REC_W_LCDCONF_FLAG;
u8  buffer[BMP_R_Byte_Max];
u32 i = 0,j = 0,k = 0;
u32 File_length=0;
u8 SendTo_PC_cfgFile=0;
u32 VCP_Receive_True_num=0;
u32 USB_Rx_Demura_Total_Num=0;
u32 USB_Rx_Demura_Total_Num_Temp=0;
u32 USB_Rx_Demura_Num=0;
u32 USB_Rx_Demura=0;
u8 USB_Rx_Demura_End_Flag=0;
u32 USB_Rx_2C3C=0;
u32 ICS307_Valid_Data=0;
u32 ICS307_Buf_Data=0;
u32 ICS307_Buf_Data1 = 0;
u8 PatternR=0,PatternG=0,PatternB=0;
u8 Pure_Color_Flag = 0;
u8 CS_Master = CS1;
u8 CS_Slaver = CS2;
u16 OLED_X0,OLED_X1,OLED_Y0,OLED_Y1,OLED_X_VALUE,OLED_Y_VALUE;
u16 LP_B7_Data,HS_B7_Data;
u8  Rec_first_line_Flag = 1;
u8 RM195_otptime = 0,RM3xx_otptime = 0,RM35x_otptime = 0;
u32 SSD28xx_Code[SSD2828_Code_Max];                         //存放 SSD2828配置 数据
u32 Timing_and_InitCode[IniCode_Max];                       //更新时 临时存放Timing和Driver IC初始化代码
u8  SSD28xxCode_count = 0;                                  //SSD2828配置代码的 行数
u8  InitCode_valid[IniCode_table_num][IniCode_Max];         //存放 Driver IC初始化代码
u16 InitCode_count=0;                                     //DriverIC初始化代码的 行数
u32 Code_length = 0;
u8  Receive_Code_flag = 0;

u8  Receive_BIN_Flag = 0;
u8  Receive_BIN_Flag1 = 0;
u8  Receive_BIN_Flag2 = 0;
u32 Receive_BIN_Length = 0;
u32 bw;

u32  Device_ID_Buf[2];
u32  Device_ID = 2;
u32  Device_Addr = 0;
//----------------------------------------------------------------------------------
u8 gamma_read_num=0;
u8 gamma_write_num=0;

/** @defgroup usbd_cdc_Private_Macros
  * @{
  */ 
/**
  * @}
  */ 
__IO  uint8_t USB_StatusDataSended = 1;
__IO  uint32_t USB_ReceivedCount = 0;
/** @defgroup usbd_cdc_Private_FunctionPrototypes
  * @{
  */

/*********************************************
   CDC Device library callbacks
 *********************************************/
static uint8_t  usbd_cdc_Init        (void  *pdev, uint8_t cfgidx);
static uint8_t  usbd_cdc_DeInit      (void  *pdev, uint8_t cfgidx);
static uint8_t  usbd_cdc_Setup       (void  *pdev, USB_SETUP_REQ *req);
static uint8_t  usbd_cdc_EP0_RxReady  (void *pdev);
static uint8_t  usbd_cdc_DataIn      (void *pdev, uint8_t epnum);
static uint8_t  usbd_cdc_DataOut     (void *pdev, uint8_t epnum);
static uint8_t  usbd_cdc_SOF         (void *pdev);

/*********************************************
   CDC specific management functions
 *********************************************/
static void Handle_USBAsynchXfer  (void *pdev);
static uint8_t  *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length);
#ifdef USE_USB_OTG_HS  
static uint8_t  *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length);
#endif
/**
  * @}
  */ 

/** @defgroup usbd_cdc_Private_Variables
  * @{
  */ 
extern CDC_IF_Prop_TypeDef  APP_FOPS;
extern uint8_t USBD_DeviceDesc   [USB_SIZ_DEVICE_DESC];

#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
    #pragma data_alignment=4   
  #endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc  [USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ;

#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
    #pragma data_alignment=4   
  #endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t usbd_cdc_OtherCfgDesc  [USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ;

#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
    #pragma data_alignment=4   
  #endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN static __IO uint32_t  usbd_cdc_AltSet  __ALIGN_END = 0;

#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
    #pragma data_alignment=4   
  #endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t USB_Rx_Buffer   [CDC_DATA_MAX_PACKET_SIZE] __ALIGN_END ;

#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
    #pragma data_alignment=4   
  #endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t APP_Rx_Buffer   [APP_RX_DATA_SIZE] __ALIGN_END ;  //其实是一个循环缓冲区


#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
    #pragma data_alignment=4   
  #endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t CmdBuff[CDC_CMD_PACKET_SZE] __ALIGN_END ;

uint32_t APP_Rx_ptr_in  = 0;    //APP_Rx_Buffer指明了其数据进来的位置,当USART 接收到数据时，将数据存储于 APP_Rx_ptr_in 指定的位置
uint32_t APP_Rx_ptr_out = 0;    //APP_Rx_Buffer指明其数据取出 的位置，当 USB 到 FIFO 中取出数据时，起始地址由 APP_Rx_ptr_out 决定
uint32_t APP_Rx_length  = 0;

uint8_t  USB_Tx_State = 0;

static uint32_t cdcCmd = 0xFF;
static uint32_t cdcLen = 0;

/* CDC interface class callbacks structure */
USBD_Class_cb_TypeDef  USBD_CDC_cb = 
{
  usbd_cdc_Init,
  usbd_cdc_DeInit,
  usbd_cdc_Setup,
  NULL,                 /* EP0_TxSent, */
  usbd_cdc_EP0_RxReady,
  usbd_cdc_DataIn,
  usbd_cdc_DataOut,
  usbd_cdc_SOF,
  NULL,
  NULL,     
  USBD_cdc_GetCfgDesc,
#ifdef USE_USB_OTG_HS   
  USBD_cdc_GetOtherCfgDesc, /* use same cobfig as per FS */
#endif /* USE_USB_OTG_HS  */
};

#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
    #pragma data_alignment=4   
  #endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
/* USB CDC device Configuration Descriptor */
__ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc[USB_CDC_CONFIG_DESC_SIZ]  __ALIGN_END =
{
  /*Configuration Descriptor*/
  0x09,   /* bLength: Configuration Descriptor size */
  USB_CONFIGURATION_DESCRIPTOR_TYPE,      /* bDescriptorType: Configuration */
  USB_CDC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */
  0x00,
  0x02,   /* bNumInterfaces: 2 interface */
  0x01,   /* bConfigurationValue: Configuration value */
  0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
  0xC0,   /* bmAttributes: self powered */
  0x32,   /* MaxPower 0 mA */
  
  /*---------------------------------------------------------------------------*/
  
  /*Interface Descriptor */
  0x09,   /* bLength: Interface Descriptor size */
  USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: Interface */
  /* Interface descriptor type */
  0x00,   /* bInterfaceNumber: Number of Interface */
  0x00,   /* bAlternateSetting: Alternate setting */
  0x01,   /* bNumEndpoints: One endpoints used */
  0x02,   /* bInterfaceClass: Communication Interface Class */
  0x02,   /* bInterfaceSubClass: Abstract Control Model */
  0x01,   /* bInterfaceProtocol: Common AT commands */
  0x00,   /* iInterface: */
  
  /*Header Functional Descriptor*/
  0x05,   /* bLength: Endpoint Descriptor size */
  0x24,   /* bDescriptorType: CS_INTERFACE */
  0x00,   /* bDescriptorSubtype: Header Func Desc */
  0x10,   /* bcdCDC: spec release number */
  0x01,
  
  /*Call Management Functional Descriptor*/
  0x05,   /* bFunctionLength */
  0x24,   /* bDescriptorType: CS_INTERFACE */
  0x01,   /* bDescriptorSubtype: Call Management Func Desc */
  0x00,   /* bmCapabilities: D0+D1 */
  0x01,   /* bDataInterface: 1 */
  
  /*ACM Functional Descriptor*/
  0x04,   /* bFunctionLength */
  0x24,   /* bDescriptorType: CS_INTERFACE */
  0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
  0x02,   /* bmCapabilities */
  
  /*Union Functional Descriptor*/
  0x05,   /* bFunctionLength */
  0x24,   /* bDescriptorType: CS_INTERFACE */
  0x06,   /* bDescriptorSubtype: Union func desc */
  0x00,   /* bMasterInterface: Communication class interface */
  0x01,   /* bSlaveInterface0: Data Class Interface */
  
  /*Endpoint 2 Descriptor*/
  0x07,                           /* bLength: Endpoint Descriptor size */
  USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
  CDC_CMD_EP,                     /* bEndpointAddress */
  0x03,                           /* bmAttributes: Interrupt */
  LOBYTE(CDC_CMD_PACKET_SZE),     /* wMaxPacketSize: */
  HIBYTE(CDC_CMD_PACKET_SZE),
#ifdef USE_USB_OTG_HS
  0x10,                           /* bInterval: */
#else
  0xFF,                           /* bInterval: */
#endif /* USE_USB_OTG_HS */
  
  /*---------------------------------------------------------------------------*/
  
  /*Data class interface descriptor*/
  0x09,   /* bLength: Endpoint Descriptor size */
  USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: */
  0x01,   /* bInterfaceNumber: Number of Interface */
  0x00,   /* bAlternateSetting: Alternate setting */
  0x02,   /* bNumEndpoints: Two endpoints used */
  0x0A,   /* bInterfaceClass: CDC */
  0x00,   /* bInterfaceSubClass: */
  0x00,   /* bInterfaceProtocol: */
  0x00,   /* iInterface: */
  
  /*Endpoint OUT Descriptor*/
  0x07,   /* bLength: Endpoint Descriptor size */
  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType: Endpoint */
  CDC_OUT_EP,                        /* bEndpointAddress */
  0x02,                              /* bmAttributes: Bulk */
  LOBYTE(CDC_DATA_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
  HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
  0x00,                              /* bInterval: ignore for Bulk transfer */
  
  /*Endpoint IN Descriptor*/
  0x07,   /* bLength: Endpoint Descriptor size */
  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType: Endpoint */
  CDC_IN_EP,                         /* bEndpointAddress */
  0x02,                              /* bmAttributes: Bulk */
  LOBYTE(CDC_DATA_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
  HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
  0x00                               /* bInterval: ignore for Bulk transfer */
} ;

#ifdef USE_USB_OTG_HS
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
    #pragma data_alignment=4   
  #endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ 
__ALIGN_BEGIN uint8_t usbd_cdc_OtherCfgDesc[USB_CDC_CONFIG_DESC_SIZ]  __ALIGN_END =
{ 
  0x09,   /* bLength: Configuation Descriptor size */
  USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,   
  USB_CDC_CONFIG_DESC_SIZ,
  0x00,
  0x02,   /* bNumInterfaces: 2 interfaces */
  0x01,   /* bConfigurationValue: */
  0x04,   /* iConfiguration: */
  0xC0,   /* bmAttributes: */
  0x32,   /* MaxPower 100 mA */  
  
  /*Interface Descriptor */
  0x09,   /* bLength: Interface Descriptor size */
  USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: Interface */
  /* Interface descriptor type */
  0x00,   /* bInterfaceNumber: Number of Interface */
  0x00,   /* bAlternateSetting: Alternate setting */
  0x01,   /* bNumEndpoints: One endpoints used */
  0x02,   /* bInterfaceClass: Communication Interface Class */
  0x02,   /* bInterfaceSubClass: Abstract Control Model */
  0x01,   /* bInterfaceProtocol: Common AT commands */
  0x00,   /* iInterface: */
  
  /*Header Functional Descriptor*/
  0x05,   /* bLength: Endpoint Descriptor size */
  0x24,   /* bDescriptorType: CS_INTERFACE */
  0x00,   /* bDescriptorSubtype: Header Func Desc */
  0x10,   /* bcdCDC: spec release number */
  0x01,
  
  /*Call Management Functional Descriptor*/
  0x05,   /* bFunctionLength */
  0x24,   /* bDescriptorType: CS_INTERFACE */
  0x01,   /* bDescriptorSubtype: Call Management Func Desc */
  0x00,   /* bmCapabilities: D0+D1 */
  0x01,   /* bDataInterface: 1 */
  
  /*ACM Functional Descriptor*/
  0x04,   /* bFunctionLength */
  0x24,   /* bDescriptorType: CS_INTERFACE */
  0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
  0x02,   /* bmCapabilities */
  
  /*Union Functional Descriptor*/
  0x05,   /* bFunctionLength */
  0x24,   /* bDescriptorType: CS_INTERFACE */
  0x06,   /* bDescriptorSubtype: Union func desc */
  0x00,   /* bMasterInterface: Communication class interface */
  0x01,   /* bSlaveInterface0: Data Class Interface */
  
  /*Endpoint 2 Descriptor*/
  0x07,                           /* bLength: Endpoint Descriptor size */
  USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
  CDC_CMD_EP,                     /* bEndpointAddress */
  0x03,                           /* bmAttributes: Interrupt */
  LOBYTE(CDC_CMD_PACKET_SZE),     /* wMaxPacketSize: */
  HIBYTE(CDC_CMD_PACKET_SZE),
  0xFF,                           /* bInterval: */
  
  /*---------------------------------------------------------------------------*/
  
  /*Data class interface descriptor*/
  0x09,   /* bLength: Endpoint Descriptor size */
  USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: */
  0x01,   /* bInterfaceNumber: Number of Interface */
  0x00,   /* bAlternateSetting: Alternate setting */
  0x02,   /* bNumEndpoints: Two endpoints used */
  0x0A,   /* bInterfaceClass: CDC */
  0x00,   /* bInterfaceSubClass: */
  0x00,   /* bInterfaceProtocol: */
  0x00,   /* iInterface: */
  
  /*Endpoint OUT Descriptor*/
  0x07,   /* bLength: Endpoint Descriptor size */
  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType: Endpoint */
  CDC_OUT_EP,                        /* bEndpointAddress */
  0x02,                              /* bmAttributes: Bulk */
  0x40,                              /* wMaxPacketSize: */
  0x00,
  0x00,                              /* bInterval: ignore for Bulk transfer */
  
  /*Endpoint IN Descriptor*/
  0x07,   /* bLength: Endpoint Descriptor size */
  USB_ENDPOINT_DESCRIPTOR_TYPE,     /* bDescriptorType: Endpoint */
  CDC_IN_EP,                        /* bEndpointAddress */
  0x02,                             /* bmAttributes: Bulk */
  0x40,                             /* wMaxPacketSize: */
  0x00,
  0x00                              /* bInterval */
};
#endif /* USE_USB_OTG_HS  */




/**
  * @}
  */ 

/** @defgroup usbd_cdc_Private_Functions
  * @{
  */ 

/**
  * @brief  usbd_cdc_Init
  *         Initilaize the CDC interface
  * @param  pdev: device instance
  * @param  cfgidx: Configuration index
  * @retval status
  */
static uint8_t  usbd_cdc_Init (void  *pdev, 
                               uint8_t cfgidx)
{
  uint8_t *pbuf;

  /* Open EP IN */
  DCD_EP_Open(pdev,
              CDC_IN_EP,
              CDC_DATA_IN_PACKET_SIZE,
              USB_OTG_EP_BULK);
  
  /* Open EP OUT */
  DCD_EP_Open(pdev,
              CDC_OUT_EP,
              CDC_DATA_OUT_PACKET_SIZE,
              USB_OTG_EP_BULK);
  
  /* Open Command IN EP */
  DCD_EP_Open(pdev,
              CDC_CMD_EP,
              CDC_CMD_PACKET_SZE,
              USB_OTG_EP_INT);
  
  pbuf = (uint8_t *)USBD_DeviceDesc;
  pbuf[4] = DEVICE_CLASS_CDC;
  pbuf[5] = DEVICE_SUBCLASS_CDC;
  
  /* Initialize the Interface physical components */
  APP_FOPS.pIf_Init();

  /* Prepare Out endpoint to receive next packet */
  DCD_EP_PrepareRx(pdev,
                   CDC_OUT_EP,
                   (uint8_t*)(USB_Rx_Buffer),
                   CDC_DATA_OUT_PACKET_SIZE);
  
  return USBD_OK;
}

/**
  * @brief  usbd_cdc_Init
  *         DeInitialize the CDC layer
  * @param  pdev: device instance
  * @param  cfgidx: Configuration index
  * @retval status
  */
static uint8_t  usbd_cdc_DeInit (void  *pdev, 
                                 uint8_t cfgidx)
{
  /* Open EP IN */
  DCD_EP_Close(pdev,
              CDC_IN_EP);
  
  /* Open EP OUT */
  DCD_EP_Close(pdev,
              CDC_OUT_EP);
  
  /* Open Command IN EP */
  DCD_EP_Close(pdev,
              CDC_CMD_EP);

  /* Restore default state of the Interface physical components */
  APP_FOPS.pIf_DeInit();
  
  return USBD_OK;
}

/**
  * @brief  usbd_cdc_Setup
  *         Handle the CDC specific requests
  * @param  pdev: instance
  * @param  req: usb requests
  * @retval status
  */
static uint8_t  usbd_cdc_Setup (void  *pdev, 
                                USB_SETUP_REQ *req)
{
  uint16_t len;
  uint8_t  *pbuf;
  
  switch (req->bmRequest & USB_REQ_TYPE_MASK)
  {
    /* CDC Class Requests -------------------------------*/
  case USB_REQ_TYPE_CLASS :
      /* Check if the request is a data setup packet */
      if (req->wLength)
      {
        /* Check if the request is Device-to-Host */
        if (req->bmRequest & 0x80)
        {
          /* Get the data to be sent to Host from interface layer */
          APP_FOPS.pIf_Ctrl(req->bRequest, CmdBuff, req->wLength);
          
          /* Send the data to the host */
          USBD_CtlSendData (pdev, 
                            CmdBuff,
                            req->wLength);          
        }
        else /* Host-to-Device requeset */
        {
          /* Set the value of the current command to be processed */
          cdcCmd = req->bRequest;
          cdcLen = req->wLength;
          
          /* Prepare the reception of the buffer over EP0
          Next step: the received data will be managed in usbd_cdc_EP0_TxSent() 
          function. */
          USBD_CtlPrepareRx (pdev,
                             CmdBuff,
                             req->wLength);          
        }
      }
      else /* No Data request */
      {
        /* Transfer the command to the interface layer */
        APP_FOPS.pIf_Ctrl(req->bRequest, NULL, 0);
      }
      
      return USBD_OK;
      
    default:
      USBD_CtlError (pdev, req);
      return USBD_FAIL;
    
      
      
    /* Standard Requests -------------------------------*/
  case USB_REQ_TYPE_STANDARD:
    switch (req->bRequest)
    {
    case USB_REQ_GET_DESCRIPTOR: 
      if( (req->wValue >> 8) == CDC_DESCRIPTOR_TYPE)
      {
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
        pbuf = usbd_cdc_Desc;   
#else
        pbuf = usbd_cdc_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM);
#endif 
        len = MIN(USB_CDC_DESC_SIZ , req->wLength);
      }
      
      USBD_CtlSendData (pdev, 
                        pbuf,
                        len);
      break;
      
    case USB_REQ_GET_INTERFACE :
      USBD_CtlSendData (pdev,
                        (uint8_t *)&usbd_cdc_AltSet,
                        1);
      break;
      
    case USB_REQ_SET_INTERFACE :
      if ((uint8_t)(req->wValue) < USBD_ITF_MAX_NUM)
      {
        usbd_cdc_AltSet = (uint8_t)(req->wValue);
      }
      else
      {
        /* Call the error management function (command will be nacked */
        USBD_CtlError (pdev, req);
      }
      break;
    }
  }
  return USBD_OK;
}

/**
  * @brief  usbd_cdc_EP0_RxReady
  *         Data received on control endpoint
  * @param  pdev: device device instance
  * @retval status
  */
static uint8_t  usbd_cdc_EP0_RxReady (void  *pdev)
{ 
  if (cdcCmd != NO_CMD)
  {
    /* Process the data */
    APP_FOPS.pIf_Ctrl(cdcCmd, CmdBuff, cdcLen);
    
    /* Reset the command variable to default value */
    cdcCmd = NO_CMD;
  }
  
  return USBD_OK;
}

/**
  * @brief  usbd_audio_DataIn
  *         Data sent on non-control IN endpoint
  * @param  pdev: device instance
  * @param  epnum: endpoint number
  * @retval status
  */
static uint8_t  usbd_cdc_DataIn (void *pdev, uint8_t epnum)
{
  if(epnum == (CDC_IN_EP&0x7F))
  {
    //DCD_EP_Flush(pdev, CDC_IN_EP);
    USB_StatusDataSended = 1;
  }
  return USBD_OK;
}
//ssd2828初始化
void SSD2828_initial_on(u8 signal_mode,u8 channel)
{
	for(i = 0;i<SSD28xxCode_count-1;i ++)	//将SSD2828的配置参数 通过SPI写入到 芯片
	{
		SSD2828_W_Reg(signal_mode,channel,(u8)(SSD28xx_Code[i]>>16),(u16)SSD28xx_Code[i]);
	}
	delay_ms(20);
}

void Driver_ic_initial_on(u8 signal_mode,u8 channel)
{
	for(i=0;i<InitCode_count;i++)			//将初始化代码 写入2828,通过2828的低速模式传送
	{		
			SSD2828_W_Array(signal_mode,channel,InitCode_valid[i],0);
	}
}

void SSD2828_signal_on(u8 signal_mode,u8 channel)
{
	for(i = 0;i<SSD28xxCode_count-1;i ++)	//将SSD2828的配置参数 通过SPI写入到 芯片
	{
		SSD2828_W_Reg(signal_mode,channel,(u8)(SSD28xx_Code[i]>>16),(u16)SSD28xx_Code[i]);
	}
	delay_ms(20);
	for(i=0;i<InitCode_count;i++)			//将初始化代码 写入2828,通过2828的低速模式传送
	{		
			SSD2828_W_Array(signal_mode,channel,InitCode_valid[i],0);
	}
//    FSMC_Pure_colour(BLACK); 
//    Load_done_HIGH;
    SSD2828_W_Reg(signal_mode,channel,(u8)(SSD28xx_Code[SSD28xxCode_count-1]>>16),(u16)SSD28xx_Code[SSD28xxCode_count-1]);
 #if InsertBlack == 1   
    delay_ms(100);
#endif
}

void SPI_signal_on(u8 SPI_Mode,u8 channel)
{
	for(i = 0;i<InitCode_count;i++)			
	{			
		if(((u8)InitCode_valid[i]==0x11)||((u8)InitCode_valid[i]==0x29))
		{
			SPI_Write_u8_Cmd(SPI_Mode,channel,(u8)InitCode_valid[i]);
			delay_ms(120);
		}
		else
		{
			SPI_Write_u8_Array(SPI_Mode,channel,(u8 *)InitCode_valid[i]);
		}
	}
}
/**
  * @brief  usbd_audio_DataOut
  *         Data received on non-control Out endpoint
  * @param  pdev: device instance
  * @param  epnum: endpoint number
  * @retval status
  */
static uint8_t  usbd_cdc_DataOut (void *pdev, uint8_t epnum)
{      
    u16 i=0;u32 TotalNum=0;
	if(epnum == (CDC_OUT_EP&0x7F))
	{
        USB_ReceivedCount = USBD_GetRxCount(pdev,epnum);
        /* Prapare EP to Receive next Cmd */
        DCD_EP_PrepareRx (pdev,CDC_OUT_EP,(uint8_t *)USB_Rx_Buffer,sizeof(USB_Rx_Buffer)); 
        if(USB_ReceivedCount>1)
        {
            if ( (USB_ReceivedCount<510)&& ( (USB_Rx_Buffer[1]&0xc0) >0) ) //----新指令格式/协议专用
			{//如果此时传过来的不是图片数据，且标志位USB_Rx_Buffer[1]的高两位大于0：此时指令格式为新版
				TotalNum=(USB_Rx_Buffer[2]+((USB_Rx_Buffer[1]&0xc0)>>6)*128);
			}//
			else TotalNum=0;//----新指令格式/协议专用
			if((USB_ReceivedCount==REC_LCDCONF_NUM)&&(USB_Rx_Demura==0)&&(NUM==0)&&(Receive_BIN_Flag == 0)&&(Receive_BIN_Flag1 == 0))      //接受的数据长度 固定   
            {//接受固定数据长度 
                if(USB_Rx_Buffer[0]==REC_LCDCONF_START)          //上位机 发送模组Timing参数、ICS307配置参数、通道数  0X0A
                {
                    Uart_rx_flag = USB_Rx_Buffer[1];  //时间标志
                    crc16_data = crc16(USB_Rx_Buffer,USB_Rx_Buffer[2]+4-2,0xFFFF);
                    if(crc16_data == ((USB_Rx_Buffer[USB_Rx_Buffer[2]+4-2]<<8)|(USB_Rx_Buffer[USB_Rx_Buffer[2]+4-1])))
                    {
                        if(REC_W_LCDCONF_FLAG == Uart_rx_flag)		//上位机 发送 LCDConfig 数据
                        {       
                            FPGA_ResetProcess();
                            Load_done_LOW;
                            
                            //配置ICS307时钟芯片
                            ICS307_Valid_Data = (u32)(USB_Rx_Buffer[16]<<24)|(u32)(USB_Rx_Buffer[15]<<16)|(u32)(USB_Rx_Buffer[14]<<8)|(u32)(USB_Rx_Buffer[13]);
                            OLED.DisMode = ((USB_Rx_Buffer[18]&0x0f)<=2) ? 0 : 1;
														OLED.RGBMode = USB_Rx_Buffer[18]&0x0f;
                            OLED.H_pixel = (OLED.DisMode == 0) ? (u16)(USB_Rx_Buffer[3]<<8)|(USB_Rx_Buffer[4]) : 2*((u16)(USB_Rx_Buffer[3]<<8)|(USB_Rx_Buffer[4]));
                            OLED.V_pixel =  (u16)(USB_Rx_Buffer[8]<<8)|(USB_Rx_Buffer[9]);
                            OLED.pixel_clk = (float)((((u16)(USB_Rx_Buffer[21]<<8)+USB_Rx_Buffer[20]))/10.0);
                            ICS307_ValidClk_Set(ICS307_Valid_Data);                        
                            OLED.SigMode = USB_Rx_Buffer[18]&0XF0;
			
                            if((OLED.SigMode == Mipi_Mode)||(OLED.SigMode == CMD_Mode))
                            {
                                write_cmd(0x1234);						//将OLED时序数据发送到FPGA
                                write_cmd((u16)(USB_Rx_Buffer[4]<<8)|(USB_Rx_Buffer[3]) );	
                                write_cmd((u16)(USB_Rx_Buffer[9]<<8)|(USB_Rx_Buffer[8]) );                                
                                write_cmd((u16)(USB_Rx_Buffer[6]<<8) ) ;                               
                                write_cmd((u16)(USB_Rx_Buffer[11]<<8) ) ;	
                                write_cmd((u16)(USB_Rx_Buffer[5]<<8) ) ;	
                                write_cmd((u16)(USB_Rx_Buffer[10]<<8 ) );	
                                write_cmd((u16)(USB_Rx_Buffer[7]<<8) ) ;	
                                write_cmd((u16)(USB_Rx_Buffer[12]<<8) ) ;	                                      
                                write_cmd((u16)(USB_Rx_Buffer[18]<<8) + ((OLED.SigMode == Mipi_Mode) ? 0x00 : 0x01 )) ;	
                                write_cmd((u16)(USB_Rx_Buffer[17]));	
                                write_cmd(0x4321); 
                            }                        
                            if(OLED.DisMode!= 0)
                                CS_Master = CS1_2;
                            else
                                CS_Master = CS1;
                            CS_Slaver = CS2;                               
                            SSD28xxCode_count = 0;
                            InitCode_count = 0;
                            Set_2828_reset(OLED.SigMode);       //复位2828和OLED模组
                            STM2PC_ERROR(pdev,CDC_IN_EP,USB_Rx_Buffer[0],Uart_rx_flag,Uart_Error_None,0);           //返回 写LCD_Config状态  ：ok                       
                        }
 /*         
						else if(REC_R_LCDCONF_FLAG == Uart_rx_flag)	//上位机 读取 LCDConfig 数据
                        {										
                            i = 0;
                            WriteAddress = Inter_Flash_Addr;
                            FLASH_If_Read(&WriteAddress, buffer1, 0,2048);	//将FLASH的模组Timing数据读取出来，准备发送给FPGA
                            for(i=0;i<16;i++)
                            {
                                    USB_Rx_Buffer[i*4]     = (u8)(buffer1[i]>>24);
                                    USB_Rx_Buffer[(i*4)+1] = (u8)(buffer1[i]>>16);
                                    USB_Rx_Buffer[(i*4)+2] = (u8)(buffer1[i]>>8);
                                    USB_Rx_Buffer[(i*4)+3] = (u8)(buffer1[i]);
                            }									
                            if((USB_Rx_Buffer[0] == 0x47)&&(USB_Rx_Buffer[1] == 0x56)&&(USB_Rx_Buffer[2] == 0x4F)&&(USB_Rx_Buffer[3] == 0x43)&&(USB_Rx_Buffer[4] == 0x6F)&&(USB_Rx_Buffer[5] == 0x6E))
                                STM2PC_LCDConfig(pdev,CDC_IN_EP,Uart_rx_flag,USB_Rx_Buffer,Uart_Error_None);       //返回 读LCD_Config状态 ：ok；将LCD_Config数据返回
                            else
                                STM2PC_LCDConfig(pdev,CDC_IN_EP,Uart_rx_flag,USB_Rx_Buffer,Uart_Error_IntFlash);	//返回 flash内部没有配置文件 ：error									
                    
                        }
	*/											
                        else if(REC_W_PATTERN_FLAG == Uart_rx_flag)	//上位机 发送 画面颜色 数据
                        {	
							STM2PC_ERROR(pdev,CDC_IN_EP,USB_Rx_Buffer[0],Uart_rx_flag,Uart_Error_None,0);
                            if(OLED.SigMode == Mipi_Mode)
                            {       
								#if DSI_Set_Window_EN == 1
                                SSD2828_Set_Window(OLED.SigMode,CS_Master,(OLED.H_pixel==390) ? 4 : 0,(OLED.H_pixel==390) ? OLED.H_pixel+4 : OLED.H_pixel,0,OLED.V_pixel);
								#endif                                

                                FSMC_Pure_colour((u32)(USB_Rx_Buffer[3]<<16)|((u32)(USB_Rx_Buffer[4]<<8)|USB_Rx_Buffer[5]));
                                 
                                Load_done_HIGH;
                                SSD2828_W_Reg(OLED.SigMode,CS_Master,0xB7,HS_B7_Data);
                                PatternR = USB_Rx_Buffer[3];
                                PatternG = USB_Rx_Buffer[4];
                                PatternB = USB_Rx_Buffer[5]; 
                            }
							else if(OLED.SigMode == CMD_Mode)           //Command 模式
		                    {
								#if DSI_Set_Window_EN == 1                    
                                SSD2828_Set_Window(OLED.SigMode,CS_Master,(OLED.H_pixel==390) ? 4 : 0,(OLED.H_pixel==390) ? OLED.H_pixel+4 : OLED.H_pixel,0,OLED.V_pixel);
								#endif
		                        SSD2828_W_RAM_Pic(OLED.pixel_clk,OLED.SigMode,CS_Master,OLED.H_pixel,OLED.V_pixel,USB_Rx_Buffer[3],USB_Rx_Buffer[4],USB_Rx_Buffer[5]);                        
		                    }
		                    else if((OLED.SigMode == SPI3_Mode)||(OLED.SigMode == SPI4_Mode))          //3线8bit SPI 模式   //4线8bit SPI 模式
		                    {
								#if SPI_Set_Window_EN == 1                                 
		                        SPI_Set_Window(OLED.SigMode,CS_Master,0, OLED.H_pixel-1,0, OLED.V_pixel-1);
								#endif
		                        SPI3_WriteRAM(OLED.SigMode,CS_Master,OLED.H_pixel,OLED.V_pixel,USB_Rx_Buffer[3],USB_Rx_Buffer[4],USB_Rx_Buffer[5]);
		                    }

                        }
                        else if(REC_R_PATTERN_FLAG == Uart_rx_flag)	//上位机 读取 画面颜色 数据
                        {		
                            STM2PC_Pattern(pdev,CDC_IN_EP,USB_Rx_Buffer[0],PatternR,PatternG,PatternB,Uart_Error_None);
                        }
                        else if(REC_R_SW_VERSION_FLAG == Uart_rx_flag)	//上位机 读取 SW 版本号
                        {
                            if((USB_Rx_Buffer[3] == FW_Version)&&(USB_Rx_Buffer[4] == FW_SubVersion))
                                STM2PC_SW_Version(pdev,CDC_IN_EP,USB_Rx_Buffer[0],Uart_rx_flag,Uart_Error_None,FW_Version, FW_SubVersion,Device_ID);
                            else 
                            {
                                STM2PC_SW_Version(pdev,CDC_IN_EP,USB_Rx_Buffer[0],Uart_rx_flag,Uart_Error_Oth,FW_Version, FW_SubVersion,Device_ID);
                                if((USB_Rx_Buffer[3] == 0)&&(USB_Rx_Buffer[4] == 0))
                                {
                                    while(1)
                                    {
                                        delay_ms(500);
                                        LED_LOW;
                                        LED2_HIGH;
                                        delay_ms(500);
                                        LED2_LOW;
                                        LED_HIGH;
                                    }
                                }
                            }
                        }
                        else if(REC_W_DeviceID_FLAG == Uart_rx_flag)	//上位机 写入ID
                        {
                            Device_ID_Buf[0] = (USB_Rx_Buffer[3]!=0) ? (u32)(USB_Rx_Buffer[3]-0x30)*10+ (u32)(USB_Rx_Buffer[4]-0x30) : (u32)(USB_Rx_Buffer[4]-0x30);
                            Device_ID = Device_ID_Buf[0];
                            FLASH_Unlock();		//芯片内部FLASH每次操作都需要解锁
                            if(Device_Addr == Device_Flash_Addr + 0x10000)
                            {
                                Device_Addr = Device_Flash_Addr;
                                FLASH_EraseSector(Device_Flash_Sect, VoltageRange_3);
                            }
                            FLASH_If_Write(&Device_Addr, Device_ID_Buf, 1);
                            FLASH_Lock();		//FLASH操作结束，锁上 
                            STM2PC_ERROR(pdev,CDC_IN_EP,USB_Rx_Buffer[0],Uart_rx_flag,Uart_Error_None,0);
                        }
						else if(REC_W_DISP_WINDOW_CONF_FLAG == Uart_rx_flag) //上位机 发送 开窗显示数据
						{
							OLED_X0=(USB_Rx_Buffer[3]<<8)|(USB_Rx_Buffer[4]);
							OLED_X1=(USB_Rx_Buffer[5]<<8)|(USB_Rx_Buffer[6]);
							OLED_Y0=(USB_Rx_Buffer[7]<<8)|(USB_Rx_Buffer[8]);
							OLED_Y1=(USB_Rx_Buffer[9]<<8)|(USB_Rx_Buffer[10]);
							OLED_X_VALUE=OLED_X1-OLED_X0;
							OLED_Y_VALUE=OLED_Y1-OLED_Y0;
							
							OLED.H_pixel = (OLED.DisMode == 0) ? OLED_X_VALUE : 2*OLED_X_VALUE;
							OLED.V_pixel =  OLED_Y_VALUE;
							SSD2828_Set_Window(OLED.SigMode ,CS_Master,OLED_X0,OLED_X1,OLED_Y0,OLED_Y1);
														
							STM2PC_ERROR(pdev,CDC_IN_EP,USB_Rx_Buffer[0],Uart_rx_flag,Uart_Error_None,0);           //返回 写LCD_Config状态  ：ok   														
						}
                    }
                }                                                                      
            }
            else if((((USB_Rx_Buffer[0]==REC_SSD_CODE_START)&&(USB_Rx_Demura==0)&&(NUM==0))||(Receive_Code_flag == 1))&&(Receive_BIN_Flag == 0))      //接受的 数据 长度非固定
            {
                if(Receive_Code_flag == 0)
                {
                    Receive_Code_flag = 1;
                    Uart_rx_flag=USB_Rx_Buffer[1]&0x0f;
                }
                for(i=0;i<USB_ReceivedCount;i++)
                    buffer[i+VCP_Receive_True_num] = USB_Rx_Buffer[i];
                
                VCP_Receive_True_num+=USB_ReceivedCount;
                
                
                if(VCP_Receive_True_num==(buffer[1]>>4)*256+buffer[2]+5)
                {
                    Receive_Code_flag = 0;
                    if((REC_W_SSD_ONE_FLAG == Uart_rx_flag)||(REC_W_SSD_FLAG == Uart_rx_flag))		//上位机  发送 SSD2828 命令
                    {
                        SSD28xxCode_count = 0;
                        STM2PC_ERROR(pdev,CDC_IN_EP,buffer[0],Uart_rx_flag,Uart_Error_None,0);
                        if(REC_W_SSD_ONE_FLAG == Uart_rx_flag)
                        {
                            if(OLED.SigMode == Mipi_Mode)  //RGB+SPI= MIPI
                            {      
                                SSD2828_W_Reg(OLED.SigMode,CS_Master,buffer[3],(u16)(buffer[4]<<8)|buffer[5]);
                            }
                            else if(OLED.SigMode == CMD_Mode)//Command
                            {
                                SSD2828_W_Reg(OLED.SigMode,CS_Master,buffer[3],(u16)(buffer[4]<<8)|buffer[5]);                                 
                            }
                            if(buffer[3] == 0xB7)
                            {
                                if(((u16)(buffer[4]<<8)|buffer[5])&0x0001)
                                    HS_B7_Data = (u16)(buffer[4]<<8)|buffer[5];
                                else
                                    LP_B7_Data = (u16)(buffer[4]<<8)|buffer[5];
                            }                           
                        }
                        else
                        {
                            if((OLED.SigMode == Mipi_Mode)||(OLED.SigMode == CMD_Mode))
                            {
                                for (i = 0; i < 512; i++)		//将2828的配置数据 转换成字
                                {
                                    if (buffer[i * 3 +3] == 0xff)
                                    {
                                            break;                    
                                    }
                                    //    0x H H H H  :   31:24->00(没作用)   23:16->寄存器地址    15:0->寄存器值(高位在前)
                                    SSD28xx_Code[SSD28xxCode_count] = ((uint32_t)buffer[i * 3 +3]<<16) + ((uint32_t)buffer[i * 3 + 1+3]<<8) + ((uint32_t)buffer[i * 3 + 2+3]);
                                    SSD28xxCode_count ++;	
                                    if(buffer[i * 3 +3] == 0xB7)
                                    {
                                        if(((u16)(buffer[i * 3 +4]<<8)|buffer[i * 3 +5])&0x0001)
                                        {
                                            HS_B7_Data = (u16)(buffer[i * 3 +4]<<8)|buffer[i * 3 +5];
                                        }
                                        else
                                            LP_B7_Data = (u16)(buffer[i * 3 +4]<<8)|buffer[i * 3 +5];                                         
                                    }                                        
                                }
																SSD2828_initial_on(OLED.SigMode,CS_Master); //download 2828 cfg
                            }                                
                            
                        } 

                    }
                    else if((REC_W_CODE_ONE_FLAG == Uart_rx_flag)||(REC_W_CODE_FLAG == Uart_rx_flag))		//上位机  发送 DriverIC code
                    {	
                        InitCode_count = 0;
                        STM2PC_ERROR(pdev,CDC_IN_EP,buffer[0],Uart_rx_flag,Uart_Error_None,0);
                        if(REC_W_CODE_ONE_FLAG == Uart_rx_flag)
                        {
                            if((OLED.SigMode == Mipi_Mode)||(OLED.SigMode == CMD_Mode))  //RGB+SPI= MIPI
                            {									
                                SSD2828_W_Array(OLED.SigMode,CS_Master,buffer,2);
                            }
                            else if((OLED.SigMode == SPI3_Mode)||(OLED.SigMode == SPI4_Mode))          //3线8bit SPI 模式   //4线8bit SPI 模式
                            {
                                for(i=0;i<buffer[2]+1;i++)
                                    buffer[i] = buffer[i+2];
                                if(buffer[2] > 1)
                                {
                                    SPI_Write_u8_Array(OLED.SigMode,CS_Master,buffer);
                                }
                                else if(buffer[2] == 1)
                                {
                                    SPI_Write_u8_Cmd(OLED.SigMode,CS_Master,buffer[1]);
                                    delay_ms(30);

                                }  
                            }
                        }
                        else
                        {
                                for (i = 3; i < 4096; i += (Code_length+1))
                                {
                                    Code_length = buffer[i];	//每一句初始化代码的 数据长度

                                    if (Code_length == 0xff)	//判断长度有255说明 ，到初始化代码的最后
                                    {
                                            break;
                                    }
                                    Timing_and_InitCode[0] =	Code_length;	//数组中的[0]：这一句初始化代码的数据长度									
                                    for (j = 1; j < Code_length+1; j++)	//递增将 初始化代码写入到数组
                                    {											
                                            Timing_and_InitCode[j] = ((uint32_t)buffer[i+j]);
                                    }									
                                    for(j=0;j<Timing_and_InitCode[0]+1;j++)			//整合一行初始化全部内容									
                                        InitCode_valid[InitCode_count][j] = (u8)Timing_and_InitCode[j];
                                    
                                    InitCode_count ++;	//即将写下一个数组(下一句初始化代码)
                                }
                                if((OLED.SigMode == Mipi_Mode)||(OLED.SigMode == CMD_Mode))  //RGB+SPI= MIPI
                                {									
                                    //SSD2828_signal_on(OLED.SigMode,CS_Master);
																		Driver_ic_initial_on(OLED.SigMode,CS_Master);
                                }
                                else if((OLED.SigMode == SPI3_Mode)||(OLED.SigMode == SPI4_Mode))          //3线8bit SPI 模式   //4线8bit SPI 模式
                                {
                                    SPI_signal_on(OLED.SigMode,CS_Master);
                                }
                        }
                        
                    }
                    else if(REC_R_CODE_FLAG == Uart_rx_flag)		//上位机  读取 DriverIC code
                    {
                    
                    }    
                    VCP_Receive_True_num = 0;
                }                
            }
            else if(  ((USB_ReceivedCount==USB_Rx_Buffer[2]+5)|(USB_ReceivedCount==TotalNum+6))   &&(USB_Rx_Demura==0)&&(NUM==0)&&(Receive_BIN_Flag == 0)&&(Receive_BIN_Flag == 0)&&(Receive_BIN_Flag1 == 0))      //接受的 数据 长度非固定
            {	//--配置DDIC,处理初始化、OTP、Gamma等功能---	//如果此时数据长度和标志位记录不符，则认为传过来的是Demura数据(主要给瑞鼎IC用)
                Uart_rx_flag=USB_Rx_Buffer[1]&0x0f;	//？
							
				if (TotalNum>0)  //临时判断传过来的新旧指令表，只有新指令表时，TotalNum才大于零
				{	crc16_data1 = crc16(USB_Rx_Buffer,TotalNum+4,0xFFFF);
					if (crc16_data1 == ((USB_Rx_Buffer[TotalNum+4]<<8)|(USB_Rx_Buffer[TotalNum+5])))
						crc16_data1=1; //crc16_data1默认为0，crc16_data1=1意味着通过新协议传过来的数据是正确的
					else 
						{crc16_data1=0;	
						}
				}//其实如果此时传输中出现错误，则....TODO
                crc16_data = crc16(USB_Rx_Buffer,USB_Rx_Buffer[2]+3,0xFFFF);
                if(crc16_data1|(crc16_data == ((USB_Rx_Buffer[USB_Rx_Buffer[2]+3]<<8)|(USB_Rx_Buffer[USB_Rx_Buffer[2]+4]))))
                {
					switch (USB_Rx_Buffer[0])
					{
						case Rec_R_Config_Start:
						//if(USB_Rx_Buffer[0]==Rec_R_Config_Start)
						{
							if(Rec_R_Config_flag == Uart_rx_flag)		//上位机  读取  配置文件 命令
								{
									WriteAddress = Inter_Flash_Addr;
									SendTo_PC_cfgFile=1;
								}
							break;
						}
						//else if(USB_Rx_Buffer[0]==REC_UPDATABIN_Start)      //接受的 数据 长度非固定      0X55
						case REC_UPDATABIN_Start:
						{
							Receive_BIN_Flag1 = 1;
							Receive_BIN_Length = (USB_Rx_Buffer[3]<<24)+(USB_Rx_Buffer[4]<<16)+(USB_Rx_Buffer[5]<<8)+USB_Rx_Buffer[6];
							USB_Rx_Buffer[4] = Uart_Error_None;
							STM2PC_RM671xx(pdev,CDC_IN_EP,USB_Rx_Buffer,USB_Rx_Buffer[2]+3);           //返回 写寄存器状态  ：ok 
							break;  
						}
						//else if(USB_Rx_Buffer[0]==HX83200)
						case HX83200:
						{
							switch (USB_Rx_Buffer[1])
							{            
								case 0x01:                                      //写寄存器
									HX83200_Write_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;	
								case 0x02:                                      //读寄存器
									HX83200_Read_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;	
								case 0x08:                                      //写Gamma数据    
									HX83200_Write_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;
								case 0x09:                                      //读Gamma数据
									HX83200_Read_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break; 
								case 0x0A://gamma otp
									HX83200_Gamma_OTP_Start(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;
															case 0x0B:
																	HX83200_Read_OTP_Time(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;
								default:	break;	
							}
						}	break; 												
						// else if(USB_Rx_Buffer[0]==NT37710)
						case NT37710:
						{
							switch (USB_Rx_Buffer[1])
							{            
								case 0x01:                                      //写寄存器
									NT37710_Write_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;	
								case 0x02:                                      //读寄存器
									NT37710_Read_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;	
								case 0x03:                                      //写寄存器
									NT37710_Write_51Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;															
								case 0x08:                                      //写Gamma数据    
									NT37710_Write_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;
								case 0x09:                                      //读Gamma数据
									NT37710_Read_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break; 
								case 0x0A://gamma otp
									NT37710_Gamma_OTP_Start(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);  break;
															case 0x0C:
																	NT37710_Write_Gamma_Short_Package(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;
								default:	break;	
							}
						}	break; 
						//else if(USB_Rx_Buffer[0]==ICN9608)
						case ICN9608:
						{
							switch (USB_Rx_Buffer[1]&0x0f)
							{            
								case 0x01:                                      //写寄存器
									ICN9608_Write_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;	
								case 0x02:                                      //读寄存器
									ICN9608_Read_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;	
								case 0x03:                                      //写寄存器
									ICN9608_Write_51Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;															
								case 0x08:                                      //写Gamma数据    
									ICN9608_Write_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;
								case 0x09:                                      //读Gamma数据
									ICN9608_Read_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break; 
								case 0x0A://gamma otp
									ICN9608_Gamma_OTP_Start(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);  break;
								case 0x0B://OTP times
									ICN9608_Read_OTP_Times(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);  break;														
								default:	break;	
							}
						}	break; 
						//else if(USB_Rx_Buffer[0]==CH13721)
						case CH13721:
						{
							switch (USB_Rx_Buffer[1]&0x0f)
							{            
								case 0x01:                                      //写寄存器
									CH13721_Write_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;	
								case 0x02:                                      //读寄存器
									CH13721_Read_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;	
								case 0x03:                                      //写寄存器
									CH13721_Write_51Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;															
								case 0x08:                                      //写Gamma数据    
									CH13721_Write_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;
								case 0x09:                                      //读Gamma数据
									CH13721_Read_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break; 
								case 0x0A://gamma otp
															case 0x0D://OTP HBM
								case 0x0E://OTP GOA
								case 0x0F://OTP ID 	
									CH13721_Gamma_OTP_Start(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);  break;
								case 0x0B://OTP times
									CH13721_Read_OTP_Times(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);  break;							
								default:	break;	
							}
						}	break; 
						case UD61720:
						{
							switch (USB_Rx_Buffer[1]&0x0f)
							{            
								case 0x01:                                      //写寄存器
									UD61720_Write_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;	
								case 0x02:                                      //读寄存器
									UD61720_Read_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;	
								case 0x03:                                      //写寄存器
									UD61720_Write_51Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;															
								case 0x08:                                      //写Gamma数据    
									UD61720_Write_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;
								case 0x09:                                      //读Gamma数据
									UD61720_Read_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break; 
								case 0x0A://gamma otp
															case 0x0D://OTP GOA
								case 0x0E://OTP POWER
								case 0x0F://OTP OTHERS	
									UD61720_Gamma_OTP_Start(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);  break;
								case 0x0B://OTP times
									UD61720_Read_OTP_Times(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);  break;							
								default:	break;	
							}
						}	break; 															
						//else if(USB_Rx_Buffer[0]==RM67120)
						case RM67120:
						{
							switch (USB_Rx_Buffer[1])
							{            
								case 0x01:                                      //写寄存器
									RM67120_Write_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;	
								case 0x02:                                      //读寄存器
									RM67120_Read_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;	
								case 0x08:                                      //写Gamma数据    
									RM67120_Write_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;
								case 0x09:                                      //读Gamma数据
									RM67120_Read_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);    break; 
								case 0x0A://gamma otp
									RM67120_Gamma_OTP_Start(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);  break;
								case 0x0B:  //回读gamma烧录次数
									RM67120_Read_OTP_Time(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data); break;
								case 0x0C://ID otp
									RM67120_ID_OTP_Start(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data); break;
								default:	break;	
							}
                                        
						}	break; 
						case RM67195:
						case RM67295:
						case RM67198:
						case RM67298:										
						//else if((USB_Rx_Buffer[0]==RM67195)||(USB_Rx_Buffer[0]==RM67295)||(USB_Rx_Buffer[0]==RM67198)||(USB_Rx_Buffer[0]==RM67298))
						{
							switch (USB_Rx_Buffer[1])
							{            
								case 0x01:                                      //写寄存器
									RM6719X_Write_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);   break;
								case 0x51:                                      //写51寄存器
									RM6719X_Write51_Register(OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);   break;                            
								case 0x02:                                      //读寄存器
									RM6719X_Read_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);  break;	
								case 0x08:   									//写Gamma数据
																	RM6719X_Write_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data); break;
								case 0x09:                                      //读Gamma数据
									RM6719X_Read_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);     break;
								case 0x0C://otp time
								{
									RM195_otptime=USB_Rx_Buffer[4];
									USB_Rx_Buffer[4] = Uart_Error_None;
									STM2PC_RM671xx(pdev,CDC_IN_EP,USB_Rx_Buffer,USB_Rx_Buffer[2]+3);           //返回 写Gamma状态  ：ok  
								}  
								break;                            
								case 0x0A://otp page1
								case 0x0D://OTP page0
								case 0x0E://OTP page2
								case 0x0F://OTP page3 	//zangqiang 20171120
								case 0x07://SPR page5   //zangqiang 20171120
								case 0x17://CMD3_ANA		//zangqiang 20171120	
								case 0x18://OTP_Page_D0 //zangqiang 20171121	
								case 0x19://OTP_Page_E0 //zangqiang 20171121
								case 0x1A://OTP_Page_10 //zangqiang 20171125	
								case 0x1B://OTP_Page_12 //zangqiang 20171125																
									RM6719X_Gamma_OTP_Start(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data,RM195_otptime);   break;
								case 0x0B://otp time read
									RM6719X_Read_OTP_Time(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data); break;   
								case 0xDD:   		// auto Gamma数据
								RM6719X_auto_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data); break;														
								default:	
									break;	
							}               
						}	break;	
						////else if((USB_Rx_Buffer[0]==RM67160)||(USB_Rx_Buffer[0]==RM67162))
						case RM67160:
						case RM67162:
						{
							switch (USB_Rx_Buffer[1])
							{      
								case 0x01:                                      //写寄存器
									RM6716X_Write_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;
								case 0x02:                                      //读寄存器
									RM6716X_Read_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;
								case 0x08:                                      //写Gamma
									RM6716X_Write_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;
								case 0x09:                                      //读Gamma
									RM6716X_Read_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data); break;
								case 0x0A:			//OTP Start
									RM6716X_Gamma_OTP_Start(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data); break;
								case 0x0B:                                      //Read OTP Time
									RM6716X_Read_OTP_Time(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data); break;
															case 0xDD:                                      // auto Gamma
									RM6716X_auto_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;
															default:break;
							}
						}	break; 
						//else if(USB_Rx_Buffer[0]==RM6D010)
						case RM6D010:
						{
							switch (USB_Rx_Buffer[1])
							{      
								case 0x01:                                      //写寄存器
									RM6D01X_Write_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;
								case 0x02:                                      //读寄存器
									RM6D01X_Read_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;
								case 0x08:                                      //写Gamma
									RM6D01X_Write_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;
								case 0x09:                                      //读Gamma
									RM6D01X_Read_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data); break;
								case 0x0A:			    //otp GammaSet1					//OTP Start
								case 0x0D:          //otp GammaSet2    
								case 0x0E:          //otp GammaSet3
									RM6D01X_Gamma_OTP_Start(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data); break;
								case 0x0B:                                      //Read OTP Time
									RM6D01X_Read_OTP_Time(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data); break;
															case 0x11:                                      // auto Gamma
									RM6D01x_Gamma_switch(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;
															case 0xDD:                                      // auto Gamma
									RM6D01X_auto_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;
															default:break;
							}
						}	break; 
						//else if(USB_Rx_Buffer[0]==RM69300)
						case RM69300:
						{
							switch (USB_Rx_Buffer[1])
							{      
								case 0x01:                                      //写寄存器
									RM693xx_Write_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
									break;
								case 0x02:                                      //读寄存器
									RM693xx_Read_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
									break;
								case 0x08:                                      //写Gamma
									RM693xx_Write_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
									break;
								case 0x09:                                      //读Gamma
									RM693xx_Read_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data); 
									break;
								case 0x0A:			//otp GammaSet1					//OTP Start
								case 0x0D:          //otp GammaSet2    
								case 0x0E:          //otp GammaSet3
								case 0x0F:          //otp goa
								case 0x10:          //otp power
								case 0x07:
									RM693xx_Gamma_OTP_Start(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data,RM3xx_otptime); 
									break;
								case 0x0B:                                      //Read OTP Time
									RM693xx_Read_OTP_Time(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data); 
									break;
								case 0x0C://otp time

									RM3xx_otptime=USB_Rx_Buffer[4];
									USB_Rx_Buffer[4] = Uart_Error_None;
									STM2PC_RM671xx(pdev,CDC_IN_EP,USB_Rx_Buffer,USB_Rx_Buffer[2]+3);           //返回 写otp time
									break;
								case 0xDD:                                      // auto Gamma
								//    RM693xx_auto_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
									break;
								case 0x11:                                      // auto Gamma
									RM693xx_Gamma_switch(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
									break;
								case 0x51:                                      //写寄存器
									RM693xx_Write_51Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
									break;
								  default:break;
							}                        
						}	break; 
						//else if(USB_Rx_Buffer[0]==RM69350)
						case RM69350:
						{
							switch(USB_Rx_Buffer[1])
							{
								case 0x01:                                      //写寄存器
									RM6935x_Write_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
									break;
								case 0x02:                                      //读寄存器
									RM6935x_Read_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
									break;
								case 0x08:                                      //写Gamma
									RM6935x_Write_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
									break;
								case 0x09:                                      //读Gamma
									RM6935x_Read_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data); 
									break;
								case 0x0A:			//otp GammaSet1					//OTP Start
								case 0x0D:          //otp GammaSet2    
								case 0x0E:          //otp GammaSet3
								case 0x0F:          //otp goa
								case 0x10:          //otp power
								case 0x07:
								RM6935x_Gamma_OTP_Start(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data,RM35x_otptime); 
								break;
								case 0x0B:                                      //Read OTP Time
								RM6935x_Read_OTP_Time(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data); 
								break;
								case 0x0C://otp time

								RM35x_otptime=USB_Rx_Buffer[4];
								USB_Rx_Buffer[4] = Uart_Error_None;
								STM2PC_RM671xx(pdev,CDC_IN_EP,USB_Rx_Buffer,USB_Rx_Buffer[2]+3);           //返回 写otp time
								break;
								case 0xDD:           // auto Gamma
								RM6935X_auto_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
								break;
								case 0x11:                                      // auto Gamma
								RM6935x_Gamma_switch(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
								break;
								case 0x51:                                      //写寄存器
								RM6935x_Write_51Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
								break;
								default:break;
							}
						}	break; 
						//else if(USB_Rx_Buffer[0]==R66455)
						case R66455:
						{	//USB_OTG_CORE_HANDLE *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8* buffer,u16 LP_B7_Data,u16 HS_B7_Data
							ProcessForIc30(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);		break;
											
						}	break; 
						//else if(USB_Rx_Buffer[0]==TC1100)
						case TC1100:
						{	
							switch(USB_Rx_Buffer[1])
							{
								case 0x01:                                      //写寄存器
										TC1100_Write_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
										break;
								case 0x02:                                      //读寄存器
										TC1100_Read_Register(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
										break;
								case 0x04:                                      //写Gamma
										TC1100_Write_Gamma(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
										break;
								case 0x05:                                      //读Gamma
										TC1100_Gamma_OTP_Start(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data); 
								break;
								default:break;
							}	break;												
						}	break; 
						//else if(FT2711 == USB_Rx_Buffer[0])
						case FT2711:
						{	ProcessForIc4B( pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
							break;
						}	break;		
						case HX83201A:
						{	
							ProcessForIc51(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
							break;												
						}	break; 
						case VTDR6100:
						{	
							ProcessForIc4D(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
							break;												
						}	break; 
						case 0x3E:
						{
							ProcessForIc3E(CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
						}	break; 
						case 0x3F:
						{
							ProcessForIc3F(CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
						}	break; 
						case 0x40:
						{
							ProcessForIc40(CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
						}	break; 
						case 0x41:
						{
							ProcessForIc41(CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
						}	break; 
						case 0x42:
						{
							ProcessForIc42(CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
						}	break; 
						case 0x43:
						{
							ProcessForIc43(CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
						}	break; 
						case 0x44:
						{
							ProcessForIc44(CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
						}	break; 
						case 0x45:
						{
							ProcessForIc45(CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
						}	break; 
						case 0x46:
						{
							ProcessForIc46(CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
						}	break; 
						case 0x47:
						{
							ProcessForIc47(CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
						}	break; 
						case 0x48:
						{
							ProcessForIc48(CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
						}	break; 
						case 0x49:
						{
							ProcessForIc49(CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
						}	break; 
						case 0x4E:
						{
							ProcessForIc4E(CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
						}	break; 
						case 0x4F:
						{
							ProcessForIc4F(CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
						}	break; 
						case 0x50:
						{
							ProcessForIc50(CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
						}	break; 
						case GenWR:
						{
							switch (USB_Rx_Buffer[1]&0xf0)
							{            
								case 0x10:                                      //写寄存器
									Generate_Write_Function(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;	
								case 0x20:                                      //读寄存器
									Generate_Read_Function(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;	
								default:	break;	
							}
						}	break; 	
						//else if(USB_Rx_Buffer[0]==DE_MURA)
						case DE_MURA:
							{
								switch(USB_Rx_Buffer[1])
								{
									//if((USB_Rx_Buffer[7] == 0x2E) || (USB_Rx_Buffer[7] == 0x3C)) // //297/298/299	||	350
									{
										case 0x01:                                      //写寄存器
												Inter_Demura_Ram(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
										break;	
										case 0x02:                                      //读寄存器
												Exit_Demura_Ram(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
										break;						 
										case 0x03:                                      //读寄存器
												Flash_Write_Demura(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
										break;	
										case 0x04:                                      //读寄存器
												Flash_Check_Demura(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
										break;												
										case 0x05:                                      //读寄存器
												Flash_Erase_Demura(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
										break;
										case 0x06:                                      //check flash ID
												Enable_Flash_Control(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
										break;	
										case 0x07:                                      //check flash ID
												Demura_Function_ON(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
										break;	
										case 0x08:                                      //check flash ID
												Demura_Function_OFF(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
										break;													
										case 0x0A:
												Flash_Write_Demura2(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
										break;
										default:
											break;												
									}
								}
							}	break; 
						
						default:	break;
						}
            }                 
            }
						else if((USB_Rx_Demura==1)||((USB_ReceivedCount>1) && (USB_Rx_Buffer[0]==0x5b)&&(NUM==0)&&(Receive_BIN_Flag == 0)&&(Receive_BIN_Flag1 == 0)))  //接受的
						{
									USB_Rx_Demura_End_Flag=0;	
							
									if(USB_Rx_Demura==0)//第一笔数据
									{												
											if(USB_ReceivedCount==5)
											{return USBD_OK;}
											//SSD2828_Set_Window(OLED.SigMode,CS_Master,0,1080,0,1920);
											USB_Rx_Demura_Total_Num=(USB_Rx_Buffer[1]<<24)+(USB_Rx_Buffer[2]<<16)+(USB_Rx_Buffer[3]<<8)+USB_Rx_Buffer[4];				
											SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBC,(u16) (USB_Rx_Demura_Total_Num)); 
											SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBD,(u16)((USB_Rx_Demura_Total_Num)>>16)); 
											//OLED.H_pixel=1080;										
											if(OLED.H_pixel*3<=4095)//2828 command单笔上限
											{
												SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBE,(u16) (OLED.H_pixel*3)); 
											}			
											else
											{
												//SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBE,(u16) (OLED.H_pixel*3/2));
												SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBE,(u16)(OLED.H_pixel));
											}                       
											SSD2828_W_Cmd(OLED.SigMode,CS_Master,0xBF);
											SSD2828_W_Cmd(OLED.SigMode,CS_Master,0x2C);
											USB_Rx_Demura=1; //进入Demura数据写入状态
									}
									for(i=0;i<USB_ReceivedCount;i++)
									{
											buffer[i+VCP_Receive_True_num] = USB_Rx_Buffer[i];  //
									}
									VCP_Receive_True_num+=USB_ReceivedCount;
									USB_Rx_Demura_Num+=USB_ReceivedCount;				
									
									//if((USB_ReceivedCount!=0x0200)&&(USB_ReceivedCount!=0x01D5))//||(USB_Rx_Demura_Num==USB_Rx_Demura_Total_Num+5)) //最后一笔
						
									if(USB_Rx_Demura_Num==USB_Rx_Demura_Total_Num+5) //最后一笔
									{
											USB_Rx_Demura_End_Flag=1;
										//	SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBE,(u16) (USB_Rx_Demura_Total_Num%OLED.H_pixel*3)); 
									}
									//(buf_flag =OLED.H_pixel*3 > 4095 ? (OLED.H_pixel*3+5) : (OLED.H_pixel*3+5))
									if((VCP_Receive_True_num==OLED.H_pixel*3+5)||(USB_Rx_Demura_End_Flag==1)) //写入单笔数据,单次写入OLED.H_pixel*3字节
									{		
											SPI_CS_Select(CS_Master,0);
											SSD2828_W_RAM_buffer_8bits_part(OLED.pixel_clk,OLED.SigMode,buffer+5,OLED.H_pixel,1,0);
											SPI_CS_Select(CS_Master,1);
											
											VCP_Receive_True_num=0;
											USB_Rx_Demura_Num-=5;
											if(USB_Rx_Demura_End_Flag==1)//最后一笔，状态重置
											{
													USB_Rx_Demura_End_Flag=0; //最后一笔结束标识
													USB_Rx_Demura_Num=0; //累计接受数
													USB_Rx_Demura=0;//进入Demura downloading标志
											}												
									}
						}
            else
            {                    
                if((NUM==0)&&(Receive_BIN_Flag == 0)&&(Receive_BIN_Flag1 == 0))
                {
                    NUM = 1; 
                    if(OLED.SigMode == Mipi_Mode)  //RGB+SPI= MIPI
                    {
						#if DSI_Set_Window_EN == 1                    
                        SSD2828_Set_Window(OLED.SigMode,CS_Master,(OLED.H_pixel==390) ? 4 : 0,(OLED.H_pixel==390) ? OLED.H_pixel+4 : OLED.H_pixel,0,OLED.V_pixel);
						#endif                   
                        if(Valid_BMP_No==0)
                        {
                            Valid_BMP_No=1;
                        }
                        else
                        {
                            Valid_BMP_No=0;
                        }
                        write_cmd(0x3456);						//将OLED时序数据发送到FPGA
                        delay_us(4);
                        write_cmd((u16)(((Valid_BMP_No*OLED.V_pixel*OLED.H_pixel)*2)>>16));				//	0:H_PIXEL	1:H_B	2:H_F	3:H_S	4:高8(单双6,8)
                        delay_us(4);
                        write_cmd((u16)((Valid_BMP_No*OLED.V_pixel*OLED.H_pixel)*2));						//	0:V_PIXEL	1:V_B	2:V_F	3:V_S	4:无效
                        delay_us(4);
                        write_cmd(0x6543);
                        delay_us(4);

                    }
                    else if(OLED.SigMode == CMD_Mode)  //Command
                    {             
						#if DSI_Set_Window_EN == 1                    
                        SSD2828_Set_Window(OLED.SigMode,CS_Master,(OLED.H_pixel==390) ? 4 : 0,(OLED.H_pixel==390) ? OLED.H_pixel+4 : OLED.H_pixel,0,OLED.V_pixel);
						#endif
                        SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBC,(u16) (OLED.H_pixel*OLED.V_pixel*3)); 
                        SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBD,(u16)((OLED.H_pixel*OLED.V_pixel*3)>>16)); 
						if(OLED.H_pixel*3<=4095)
						{
							SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBE,(u16) (OLED.H_pixel*3)); 
						}			
						else
						{
							SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBE,(u16)(OLED.H_pixel*3/2)); 
						}
                        SSD2828_W_Cmd(OLED.SigMode,CS_Master,0xBF);
                        SSD2828_W_Cmd(OLED.SigMode,CS_Master,0X2C);
                    }
                    else if((OLED.SigMode == SPI3_Mode)||(OLED.SigMode == SPI4_Mode))          //3线8bit SPI 模式   //4线8bit SPI 模式
                    {
						#if SPI_Set_Window_EN == 1                       
                        SPI_Set_Window  (OLED.SigMode,CS_Master,0, OLED.H_pixel-1,0, OLED.V_pixel-1);
						#endif
                        SPI_Write_code  (OLED.SigMode,CS_Master ,0xFE,0x01);
                        SPI_Write_code  (OLED.SigMode,CS_Master ,0x04,0x80);
                        SPI_Write_code  (OLED.SigMode,CS_Master ,0xFE,0x00);
                        SPI_Write_code  (OLED.SigMode,CS_Master ,0xC4,0x31);        // SPI3-SP3T 2Wire
                    }    
                }
                
                if((NUM==1)&&(Receive_BIN_Flag == 0)&&(Receive_BIN_Flag == 0))
                {
                    for(i=0;i<USB_ReceivedCount;i++)
                        buffer[i+VCP_Receive_True_num] = USB_Rx_Buffer[i];
                
                    VCP_Receive_True_num+=USB_ReceivedCount;
                    if(VCP_Receive_True_num == OLED.H_pixel*3)
                    {     
                        if(OLED.SigMode == Mipi_Mode)  //RGB+SPI= MIPI
                        {
                            SSD2828_W_RAM_buffer_8bits_part(OLED.pixel_clk,OLED.SigMode,buffer,OLED.H_pixel,1,OLED.DisMode);
                        }
                        else if(OLED.SigMode == CMD_Mode)  //Command
                        {	
                            SPI_CS_Select(CS_Master,0);
                            SSD2828_W_RAM_buffer_8bits_part(OLED.pixel_clk,OLED.SigMode,buffer,OLED.H_pixel,1,0);
                            SPI_CS_Select(CS_Master,1);
                        }
                        else if((OLED.SigMode == SPI3_Mode)||(OLED.SigMode == SPI4_Mode))          //3线8bit SPI 模式   //4线8bit SPI 模式
                        {    
                            SPI_WriteRAM_buffer_part(OLED.SigMode,CS_Master,buffer,OLED.H_pixel,1,Rec_first_line_Flag);
                            if(Rec_first_line_Flag == 1)
                                Rec_first_line_Flag = 0;
                        } 
                        VCP_Receive_True_num=0;
                    }	
                }
            }        
        } 
        else if((USB_ReceivedCount==1) && (USB_Rx_Buffer[0]==0X5A) &&(NUM == 1))  //图片接受完成标志
        {            
            NUM=0;
            if(OLED.SigMode == Mipi_Mode)
            {
                Load_done_HIGH;
                FSMC_BMP_NUM(Valid_BMP_No);                     //当前画面序号
            }
            STM2PC_ERROR(pdev,CDC_IN_EP,0x0A,0x03,Uart_Error_None,0);           //返回 写LCD_Config状态  ：ok  
        } 
				
        
	}
    return USBD_OK;
}

/**
  * @brief  usbd_audio_SOF
  *         Start Of Frame event management
  * @param  pdev: instance
  * @param  epnum: endpoint number
  * @retval status
  */
static uint8_t  usbd_cdc_SOF (void *pdev)
{      
  static uint32_t FrameCount = 0;
  
  if (FrameCount++ == CDC_IN_FRAME_INTERVAL)
  {
    /* Reset the frame counter */
    FrameCount = 0;
    
    /* Check the data to be sent through IN pipe */
    Handle_USBAsynchXfer(pdev);
  }
  
  return USBD_OK;
}

/**
  * @brief  Handle_USBAsynchXfer
  *         Send data to USB
  * @param  pdev: instance
  * @retval None
  */
static void Handle_USBAsynchXfer (void *pdev)
{
  uint16_t USB_Tx_ptr;
  uint16_t USB_Tx_length;
  
  if(USB_Tx_State != 1)
  {
      //当APP_Rx_ptr_out 达到 APP_RX_DATA_SIZE 时，将其置0，
      //也就是在循环缓冲区中绕了一圈回到缓冲区起始地址。
    if (APP_Rx_ptr_out == APP_RX_DATA_SIZE)
    {
      APP_Rx_ptr_out = 0;
    }
     //当 APP_Rx_prt_out 赶上 APP_Rx_ptr_in 时，证明 Buffer 里边的数据已经发送完毕，返回   
    if(APP_Rx_ptr_out == APP_Rx_ptr_in)     //Buffer 里边的数据已经发送完毕
    {
      USB_Tx_State = 0; 
      return;
    }
    
    if(APP_Rx_ptr_out > APP_Rx_ptr_in) /* rollback */
    { 
      APP_Rx_length = APP_RX_DATA_SIZE - APP_Rx_ptr_out;
    
    }
    else 
    {
      APP_Rx_length = APP_Rx_ptr_in - APP_Rx_ptr_out;
     
    }
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
     APP_Rx_length &= ~0x03;
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
    
    if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE)
    {
      USB_Tx_ptr = APP_Rx_ptr_out;
      USB_Tx_length = CDC_DATA_IN_PACKET_SIZE;
      
      APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE;	
      APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE;
    }
    else
    {
      USB_Tx_ptr = APP_Rx_ptr_out;
      USB_Tx_length = APP_Rx_length;
      
      APP_Rx_ptr_out += APP_Rx_length;
      APP_Rx_length = 0;
    }
    USB_Tx_State = 1; 

    DCD_EP_Tx (pdev,
               CDC_IN_EP,
               (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr],
               USB_Tx_length);
  }  
  
}

/**
  * @brief  USBD_cdc_GetCfgDesc 
  *         Return configuration descriptor
  * @param  speed : current device speed
  * @param  length : pointer data length
  * @retval pointer to descriptor buffer
  */
static uint8_t  *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length)
{
  *length = sizeof (usbd_cdc_CfgDesc);
  return usbd_cdc_CfgDesc;
}

/**
  * @brief  USBD_cdc_GetCfgDesc 
  *         Return configuration descriptor
  * @param  speed : current device speed
  * @param  length : pointer data length
  * @retval pointer to descriptor buffer
  */
#ifdef USE_USB_OTG_HS 
static uint8_t  *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length)
{
  *length = sizeof (usbd_cdc_OtherCfgDesc);
  return usbd_cdc_OtherCfgDesc;
}
#endif
/**
  * @}
  */ 

/**
  * @}
  */ 

/**
  * @}
  */ 

/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
